from bot.enterprise_wechat_gpt.config.conf import *
import re


def find_allidx(word_list, final_utter):
    """word_list每个关键词 在final_utter里 所有出现位置的索引"""
    # word_idx = {}
    # for word in word_list:
    #     n = len(word)
    #     for i in range(len(final_utter)):
    #         if i+n <= len(final_utter) and final_utter[i: i+n] == word:
    #             if word not in word_idx:
    #                 word_idx[word] = []
    #             word_idx[word].append(i)
    word_idx = []
    for word in word_list:
        n = len(word)
        for i in range(len(final_utter)-n+1):
            t = final_utter[i: i+n]
            if t == word:
                start = i
                end = i + n
                word_idx.append([start, end])
    return word_idx


def check_min_distance_keyword(url_idx, keyword_to_url, sentence):
    # 惩罚\n\n断句符的距离计算
    sentence = sentence.replace('\n\n', '$'*30)
    replace_keywords = []
    for ui in url_idx:
        min_distance = 1000
        keyword = ''
        for k, url in keyword_to_url.items():
            index = sentence.find(k)
            while index != -1:
                if ui[0] > index:
                    distance = ui[0] - index
                else:
                    distance = 2 * (index - ui[1])

                if distance < min_distance:
                    min_distance = distance
                    keyword = k
                index = sentence.find(k, index + 1)
        replace_keywords.append(keyword)

    return replace_keywords


def compute_near(word_idx, idx):   # word_idx = {'金条': [5], '提额': [7, 10]} 或者 word_idx = {'金条': [5]}
    """word_idx集合里 和idx 最近距离和前置最近距离"""
    word_idx_ = [i for k in word_idx for i in word_idx[k]]
    # print('compute_near_debug: ', word_idx_, idx)
    before, absolute = float('inf'), float('inf')
    for i in word_idx_:
        gap = idx - i   # 词i 在词idx前面
        if gap > 0:
            before = min(gap, before)
        absolute = min(abs(gap), absolute)
    return before, absolute
def utter_replace_url(url_idx, final_utter, target_url):
    """存在多个url和一个产品，确定最终插入相应产品url的位置"""
    min_idx = float('inf')
    for url in url_idx:
        tmp_min = min(url_idx[url])
        if tmp_min < min_idx:
            min_idx = tmp_min
        final_utter = final_utter.replace(url, '')
    return final_utter[:min_idx] + target_url + final_utter[min_idx:]

def url_product_replace(url_idx, jintiao_idx, card_idx, final_utter,
                        urls = {"金条": " http://3.cn/10-bcNHyX ", "信用卡": " http://3.cn/10bc-6rUG "}):
    """存在多个url和多个产品关键字，确定最终插入相应产品url的位置"""
    res_utter = final_utter
    for url in url_idx:
        res_utter = res_utter.replace(url, '')

    # step1. 确定每个url对应的的是哪种产品：金条or信用卡；url第一次出现位置与相应产品词 距离
    url_prod = {}
    for url in url_idx:
        url_jintiao_before, url_jintiao_absolute = compute_near(jintiao_idx, min(url_idx[url]))
        url_card_before, url_card_absolute = compute_near(card_idx, min(url_idx[url]))
        #print('===>step1', url, url_jintiao_before, url_card_before, url_jintiao_absolute, url_card_absolute)
        if url_jintiao_before == float('inf') or url_card_before == float('inf'):   # 前置距离 至少有一个不存在，比较 绝对距离
            if url_jintiao_absolute == float('inf') and url_card_absolute == float('inf'):
                url_prod[url] = '不确定'
            elif url_jintiao_absolute <= url_card_absolute:
                url_prod[url] = '金条'
            else:
                url_prod[url] = '信用卡'
        else:
            if url_jintiao_before <= url_card_before:   # 前置距离 都存在，取较近的
                url_prod[url] = '金条'
            else:
                url_prod[url] = '信用卡'

    # step2. 找出 金条url、信用卡url，最早出现位置
    min_idx1, min_idx2 = float('inf'), float('inf')
    mark_replace_url1, mark_replace_url2 = '', ''
    for url in url_prod:
        if url_prod[url] == '不确定':
            pass
        elif url_prod[url] == '金条':
            if min(url_idx[url]) < min_idx1:
                min_idx1 = min(url_idx[url])
                mark_replace_url1 = url
        elif url_prod[url] == '信用卡':
            if min(url_idx[url]) < min_idx2:
                min_idx2 = min(url_idx[url])
                mark_replace_url2 = url
    #print('===>step2', url_prod, min_idx1, min_idx2)

    # step3. 对产品url最早出现位置 替换为指定url，其余位置 替换为空
    if min_idx1 == float('inf') and min_idx2 == float('inf'):   # 未命中 产品关键词
        if len(url_idx) == 1:   # 1个url => url是金条or信用卡的；不确定url是哪种产品的，替换成金条的
            # print('mark-product-keywords: {}'.format(final_utter))
            if urls['信用卡'].replace(' ', '') in url_idx or urls['金条'].replace(' ', '') in url_idx:
                res_utter = final_utter
            else:
                min_idx_url = min([i for k in url_idx for i in url_idx[k]])
                mark_replace_url = list(url_idx.keys())[0]
                res_utter = final_utter[ : min_idx_url] + urls['金条'] + final_utter[min_idx_url+len(mark_replace_url) : ]
        else:   ################## TODO 有多个不同url，且产品无法确定
            min_idx_url = min([i for k in url_idx for i in url_idx[k]])
            res_utter = res_utter[ : min_idx_url] + urls['金条'] + res_utter[min_idx_url : ]
    elif min_idx1 == float('inf'):
        res_utter = final_utter[ : min_idx2] + urls['信用卡'] + final_utter[min_idx2+len(mark_replace_url2) : ]
    elif min_idx2 == float('inf'):
        res_utter = final_utter[ : min_idx1] + urls['金条'] + final_utter[min_idx1+len(mark_replace_url1) : ]
    else:
        if min_idx1 <= min_idx2:
            res_utter = final_utter[ : min_idx1] + urls['金条'] + final_utter[min_idx1+len(mark_replace_url1) : min_idx2] + \
                        urls['信用卡'] + final_utter[min_idx2+len(mark_replace_url2) : ]
        else:
            res_utter = final_utter[ : min_idx2] + urls['信用卡'] + final_utter[min_idx2+len(mark_replace_url2) : min_idx1] + \
                        urls['金条'] + final_utter[min_idx1+len(mark_replace_url1) : ]
    return res_utter


def deal_urlRevise(final_utter):
    keyword_to_url = {
        '金条': ' http://3.cn/10-bcNHyX ',
        # '提额': ' http://3.cn/10-bcNHyX ',
        '借款': ' http://3.cn/10-bcNHyX ',
        '信用卡': ' http://3.cn/10bc-6rUG ',
        # '办理': ' http://3.cn/10bc-6rUG ',
        # '负责这类问题': 'https://3.cn/1G-RII6c',
        # '负责这个问题': 'https://3.cn/1G-RII6c',
    }
    # 不更改的url
    passed_urls = ['couponExchange/vouchers', '3.cn/1G-RII6c']
    # 话术空直接返回
    if not final_utter:
        return final_utter
    # url解析
    pattern = r'https*://[A-Za-z0-9_./-]+|3.cn/[A-Za-z0-9_./-]+|\u3010[^\u4e00-\u9fa5^\u3010]{10,}\u3011'
    url_context_ = re.findall(pattern, final_utter)
    # 仅过滤图像不去重
    url_context = [i for i in url_context_ if '.png' not in i]
    # url空直接返回
    if len(url_context) == 0:
        return final_utter
    # 每个url的起始位置
    url_idx = find_allidx(url_context, final_utter.replace('\n\n', '$'*30))   # 每个url 在final_utter里 对应的起始位置

    replace_keyword = check_min_distance_keyword(url_idx, keyword_to_url, final_utter)
    for url, rk in zip(url_context, replace_keyword):
        if any([pu in url for pu in passed_urls]) or not rk:
            continue
        final_utter = final_utter.replace(url, keyword_to_url.get(rk, ''))

    return final_utter




def deal_appEnter(final_utter):
    # 只有提额的入口必须是app，其余金条业务入口都可以是金条url；信用卡申请相关业务入口都可以是信用卡url
    keyword_to_url = {
        '金条': ' http://3.cn/10-bcNHyX ',
        # '提额': ' http://3.cn/10-bcNHyX ',
        '借款': ' http://3.cn/10-bcNHyX ',
        '信用卡': ' http://3.cn/10bc-6rUG ',
        # '办理': ' http://3.cn/10bc-6rUG ',
        # '负责这类问题': 'https://3.cn/1G-RII6c',
        # '负责这个问题': 'https://3.cn/1G-RII6c',
    }
    final_utter_ = re.sub(r"(App|APP|aPP|APp|ApP|apP|aPp)", 'app', final_utter, flags=re.DOTALL).strip()
    pattern = r"(app借款)*.*(无法|不能)+(参加|参与)+企微.*活动+"   # app借款是无法参与企微特邀活动的哈~
    utter_list = re.split('[？。~]', final_utter_)
    utter_list_ = [i for i in utter_list if len(i) > 1]
    for i in range(len(utter_list_)):
        tmp_utter = utter_list_[i]
        if '提额' in tmp_utter or '提升额度' in tmp_utter or '还款' in tmp_utter or '登录' in tmp_utter or '企业主贷' in tmp_utter:
            continue
        elif re.match(pattern, tmp_utter):
            continue
        else:
            utter_list_[i] = re.sub(r"(京东.*app|app借款|金条app|京东商城|京东官网|金融app|app首页)",
                                    '企微活动链接', tmp_utter, flags=re.DOTALL)\
                .replace('或企微活动链接', '')\
                .replace('企微活动链接', '企微活动链接【{}】'.format(keyword_to_url['金条']))
                # 企微活动链接是无法参与企微特邀活动的哈
    return '~'.join(utter_list_)



def deal_emoji(final_utter):
    delete_list = r"""(\[微笑\]|\[吐\]|\[偷笑\]|\[咒骂\]|\[再见\]|\[擦汗\]|\[坏笑\]|\[右哼哼\]|\[鄙视\]|\[阴险\]|\[亲亲\]|\[奸笑\]|\[汗\]|\[Emm\]|\[旺柴\]|\[裂开\]|\[嘴唇\]|\[菜刀\]|\[炸弹\]|\[便便\]|
    \[占位\]|\[庆祝\]|\[烟花\]|\[爆竹\]|\[愉快\]|\[呲牙\]|\[耶\]|\[破涕为笑\]|\[笑脸\]|\[鼓掌\]|\[憨笑\])"""
    final_utter_ = re.sub(delete_list, '', final_utter, flags=re.DOTALL).strip()
    match = re.search(delete_list, final_utter)
    if match:
        logging.warning(f"出现不合适话术:表情符号: [{match.group()}]")
    # if final_utter_ == '': final_utter_ = '~'
    return final_utter_


def text_clean(final_utter):
    error_correction_dict = {"呵呵，": "", "京卡": "京东联名信用卡", "音条": "金条", "金小鑫": "京小鑫",
                             "哈哈，": "", "祝您生活愉快": "祝您生活幸福", "愉快": "舒心",
                             "开心": "荣幸", "高兴": "荣幸", "太好了": "很不错", "惊喜": "欣喜",
                             "皆大欢喜": "更好啦"
                             }
    for k, v in error_correction_dict.items():
        if k in final_utter:
            logging.warning(f"出现不合适话术: [{k}], 替代为: [{v}]")
            # print(f"出现不合适话术: [{k}]")
            final_utter = final_utter.replace(k, v)
    return final_utter


hidden_character = " \x02\x03 "


# 添加隐藏字符串
def join_hidden_character(final_utter):
    if '\n\n' in final_utter:
        utters = final_utter.split("\n\n")
        return (hidden_character + "\n\n").join(utters) + hidden_character
    else:
        return final_utter + hidden_character


def join_hidden_char_for_output(output: dict):
    transfer = output.get("transfer", False)
    if not transfer:
        final_utter = output['text']['content']
        if final_utter is not None:
            output['text']['content'] = join_hidden_character(final_utter)
    return output


def split_text(text, max_len=50):
    indicators = ['。',  '～', '~', '！', '!', '？', '?', '；', ';']
    pattern = '|'.join('(?<={})'.format(re.escape(ind)) for ind in indicators)
    sentences = re.split(pattern, text)

    chunks = []
    chunk = ''
    for sentence in sentences:
        if len(chunk) + len(sentence) <= max_len:
            chunk += sentence
        else:
            chunks.append(chunk)
            chunk = sentence

    if chunk:
        chunks.append(chunk)

    return chunks






if __name__ == '__main__':
    check_list1 = [
        'eg1. 了解了，现在您可以去尝试金条借款申请。系统会综合评估您的信用情况，具体结果以审核为准。如果申请成功，那就太棒了！'
        '如果不成功，也没关系，我们之后再尝试。\n👉去借款【3.cn/10auq-IiO 】\n'
        '💡温馨提示：金条借款0手续费，还款灵活，叠加优惠券更划算哟~保持良好的信用记录，对您未来的金融服务是很有帮助的。',   # 11111-a
        'eg2. 您已经申请参加了活动，请点击专属链接【http://3.cn/10bc-6rUG】参与金条借款，获得额度调整机会哦！'
        '借款成功后请告诉我，我会帮您核实并关注后续优惠活动的哟~祝您顺利！💪',
        'eg3. 您好，我是您的专属金条管家，全程的陪伴期待为您提供更加贴心的服务。 （温馨提示：我的工作时间是工作日9点-18点，其他时间有问题您也可以给我留言，我看到会及时间回复您） ',
        '领取3元还款券：点击 【https://jrces.jd.com/couponExchange/vouchers?activityId=59M2x30731132450913920Qe】',

        'eg4. 同时，您可以考虑申请京东联名信用卡，解决您的资金需求。这个链接【http://3.cn/10-bcNHyX可以申请。',   # 11111-b
        'eg5. 了解您没有找到其他提额方式，您可以考虑申请京东联名信用卡，最高额度可达50万（以银行评估为准），使用信用卡消费有免息期，既有贷款功能又可消费使用。'
        '这个链接【http://3.cn/10bc-6rUG】可以申请。祝您顺利解决问题~',
        'eg6. 信用卡申请的年龄限制是需要年满18周岁，具有完全民事行为能力，有合法稳定收入来源及偿付能力，且资信良好。您可以根据自己的实际情况尝试申请哦~'
        '点击这里【http://3.cn/109IqIj-S】进行申请，申请成功后告诉我一声，我会帮您查看进度。',

        'eg7. 了解您的情况。金条秒拒可能与您的征信、收入状况等多种因素有关。您可以先关注金条app内的提额活动，根据提示进行操作提高额度。'
        '此外，如果您近期有资金需求，您可以考虑申请京东联名信用卡，额度较高且有免息期，也是个不错的选择。点击【http://3.cn/10-bcNHyX】了解详情嘛？',   # 11111-c
        'eg8. 借款成功回复【1】',
        'eg9. 😊这边给您申请一张借款优惠券，您通过链接【http://3.cn/10bc-6rUG 】借款参与我们的内部活动，这边可以帮您申请后续活动期间的使用优惠。'
        '限时福利，建议您尽快使用哦！',
        'eg10. 借款 http://3.cn/10-b55Nyz ',
        'eg11. 好的，那先别急，让我来帮您看看~ 您可以尝试通过我们的专属链接【https://jrces.jd.com/couponExchange/vouchers?activityId=59M2x30731132450913920Qe】来进行借款操作，点击上方专属链接借款成功后，'
        '回复【1】，这样我可以帮您核实一下哈。您试试这个链接能不能打开，看看是否可以借款呢？',
        'eg12. 点击链接：http://3.cn/10bc-6rUG',
        'eg13. 点击链接：3.cn/10auq-IiO',
        'eg14. 点击链接：3.cn/10auq-IiO，或者http://3.cn/109aR6L-I，您可以都看看',

        'eg15. 金条活动借款【3.cn/10auq-IiO 】，给您申请一张借款优惠券，记得点击链接http://3.cn/10bc-6rUG借款~',   # 22222-A
        'eg16. 新用户办卡申请【3.cn/10auq-IiO 】，京东联名信用卡可用于在线消费，发给您【http://3.cn/10-bcNHyX】看看吗？',   # 22222-B
        'eg17. 您先尝试下金条提额，提额方法点击这里【http://3.cn/109aR6L-I 】，用【http://3.cn/109IqIj-S】可以申请京东联名信用卡。',   # 22222-C
        'eg18. 您先尝试下金条提额，提额方法点击这里【http://3.cn/109aR6L-I 】，同时，申请京东联名信用卡点击这里【http://3.cn/109IqIj-S】。',
        'eg19. 非常抱歉，目前金条还款不支持支付宝方式。建议您使用京东金融APP的还款功能或者绑定银行卡进行还款。如果有其他问题，欢迎随时咨询。',
        'eg20. 🤗您好，金条贷款是京东金融为用户提供的一种借款服务。系统会根据您账户的消费行为、消费习惯、还款能力、还款状况等综合评估，给出相应的额度。您可以登录京东金融App，点击“金条借款”，查看您的额度和具体信息。更有优惠活动等着您，有兴趣可以参加哦！'

    ]
    #for final_utter in check_list1:
    #    res = deal_urlRevise(final_utter)
    #    print(res, '\n\n')


    check_list2 = [
       'idx0：您打开京东金融APP，点击【金条借款】-【我的】-【我的额度】，查看【提额专区】，看看能不能看到提额入口。请您根据页面展示的提额方式，告诉我您可以看到哪些提额方案，我会为您提供具体的操作指导。',
       'idx1：App借款是无法参与企微特邀活动的哈~ ',
       'idx2：了解您的情况。金条秒拒可能与您的征信、收入状况等多种因素有关。您可以先关注金条app内的提额活动，根据提示进行操作提高额度。此外，如果您近期有资金需求，您可以考虑申请京东联名信用卡，额度较高且有免息期，也是个不错的选择。点击【http://3.cn/10bc-6rUG】了解详情嘛？',
       'idx3：目前没有白条分期优惠券的活动，您可以关注京东金融APP或京东商城官网查看最新的优惠活动。不过，我们有微信专属的借款优惠活动，我可以帮您申请一张息费折扣券，具体使用规则和优惠金额以您页面显示为准哈~需要现在帮您申请吗？',
       'idx4：非常抱歉，目前金条还款不支持支付宝方式。建议您使用京东金融APP的还款功能或者绑定银行卡进行还款。如果有其他问题，欢迎随时咨询。',
       'idx5--：🤗您好，金条贷款是京东金融为用户提供的一种借款服务。系统会根据您账户的消费行为、消费习惯、还款能力、还款状况等综合评估，给出相应的额度。您可以登录京东金融App，点击“金条借款”，查看您的额度和具体信息。更有优惠活动等着您，有兴趣可以参加哦！',
       'idx6：小鑫为您发起优惠活动倒计时🔥 马上要结束了哦~ 小鑫不想您错过优惠呀！建议您现在点击链接【http://3.cn/10-bcNHyX】借款参与活动，很多客户都是通过该通道来活跃借款状态的，这有助于系统重新评估金条借款需求，调整额度和利率，具体以您页面为准。您借款成功回复【1】我帮您核实呢，下次再有优惠活动小鑫优先通知您！另外App借款是无法参与企微特邀活动的哈~',
       'idx7：您可以按照以下步骤进行企业主贷的申请：1. 打开京东金融App2. 在页面上方的搜索栏输入“企业主贷”3. 找到并点击【企业主贷】-【领取额度】4. 按照页面引导操作完成就可以了。首次贷款还有机会获得息费减免的名额哦。借款完成后别忘了跟我说一声呀~祝您申请顺利！',
       'idx8：请问您现在手边方便打开京东app吗~您可以在app首页点击"金融"进入->选择”金条“->看到界面中的"我的金条"查看您的金条额度哈~ 如果有任何疑问，随时告诉我哦',
       'idx9：是的，不好意思，我刚刚指引错误~您可以在京东乐app中操作借款~请点击【我的】-【京东金条】，选择借款金额和1个月期限，按提示完成借款申请~成功借款后您将享受30天免息优惠~如有疑问，请随时联系',

    ]
    for final_utter in check_list2:
        res = deal_appEnter(final_utter)
        print(res)



    check_list3 = ['eg1.这说明您的资质比较好[赞]，本月刚好还有活动哈，帮助您获得后续额度调整的机会和优惠申请，您可以直接参与 http://3.cn/10-bcNHyX 借款～'
                   '你操作完成后，回复【1】我帮您核实呢，下次再有优惠活动小鑫优先通知您哦！',
                   'eg2.了解您目前暂无借款需求~[微笑]请保持关注，如有贷款需求时及时使用金条~我会在有优惠活动时第一时间通知您的，祝您生活愉快～',
                   'eg3.10万，[炸弹]',
                   'eg4.[旺柴][旺柴]',
                   '咦，看来您确实有些用款需求呢[奸笑]首先，对于金条额度的问题，别着急，那就让我帮您找找解决方案。能麻烦您告诉我，您大概需要多少资金呢？是为了解决什么问题呢？打算借款多长时间呢？这样我可以更好的为您推荐合适的贷款方案哦~'
                   ]
    for final_utter in check_list3:
       res = deal_emoji(final_utter)
       print(res)

    final_utter = '呵呵，头像并不是本人，这是我们公众形象代言哦。如果您有其他问题，或者对音条或者京卡有什么需要解答的，都可以随时告诉我，我会尽快帮您解答的。'
    print(text_clean(final_utter))

    fin = join_hidden_character("了解了您的需求，1500元还信用卡，\n\n如果金条额度已用完，可以考虑申请京东联名信用卡哦。\n\n这样可以助您周转，还能享受到多种权益。您可以通过这个链接【http://3.cn/10bc-6rUG】查看详情并申请。")
    print(fin)
    print(fin.split("\n\n"))




